import java.awt.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

@SuppressWarnings("unused")
/**
 * Ez az osztaly felelos a kigyoert, a kinezeteleert, a novelesert...
 */
public class Snake {

	private int direction;
	private int left, top;
	private Point[] arr ;
	private int numberOfParts;
	
	 /**
	 * A konstruktor letrehoz egy 5 elemu kigyot,majd  beallitja az iranyt.
	 */
	public Snake () {
		left = SnakeC.SNAKE_START_X;
		top = SnakeC.SNAKE_START_Y;
		direction = SnakeC.SNAKE_LEFT;
		arr = new Point[SnakeC.MAX_BODY_PARTS];
		arr[0] = new Point( SnakeC.SNAKE_START_POINT );
		arr[1] = new Point( arr[0].x+SnakeC.SIZE, SnakeC.SNAKE_START_Y);
		arr[2] = new Point( arr[1].x+SnakeC.SIZE, SnakeC.SNAKE_START_Y);
		arr[3] = new Point( arr[2].x+SnakeC.SIZE, SnakeC.SNAKE_START_Y);
		arr[4] = new Point( arr[3].x+SnakeC.SIZE, SnakeC.SNAKE_START_Y);
		numberOfParts = 5;
	}
	
	/**
	 * A metodus noveli a kigyo aktualis hosszat egyel.
	 * Majd attol fuggoen, hogy milyen iranyba van, hozza ad egy uj testelemet.
	 */
	public void add(){
		if ( direction == SnakeC.SNAKE_UP ) {
			arr[numberOfParts] = new Point( arr[numberOfParts-1].x,arr[numberOfParts-1].y+SnakeC.SIZE);
		} else if ( direction == SnakeC.SNAKE_DOWN ) {
			arr[numberOfParts] = new Point( arr[numberOfParts-1].x,arr[numberOfParts-1].y-SnakeC.SIZE);
		} else if ( direction == SnakeC.SNAKE_RIGHT ) {
			arr[numberOfParts] = new Point( arr[numberOfParts-1].x-SnakeC.SIZE,arr[numberOfParts-1].y);
		} else if ( direction == SnakeC.SNAKE_LEFT ) {
			arr[numberOfParts] = new Point( arr[numberOfParts-1].x+SnakeC.SIZE,arr[numberOfParts-1].y);
		}
		numberOfParts++;
	}
	
	/**
	 * A kigyo kirajzolasat valositja meg ez a metodus, vegig jarja a kigyo testelemeit es kirajzolja oket.
	 */
	public void drawSnake( Graphics g ) throws IOException {
		Point r;
		for (int i=0; i<numberOfParts; i++ ) {
			r = arr[i];
			if (i==0)
				g.drawImage(ImageIO.read(new File("res\\snake\\narancs.png")), r.x, r.y, null);
			else
				g.drawImage(ImageIO.read(new File("res\\snake\\csikkek.png")), r.x, r.y, null);
		}
	}
	
	/**
	 * A kigyo fejenek a koordinatait teriti vissza Point tipuskent.
	 */
	public Point getSnakeHead(){
		return arr[0];
	}
	
	/**
	 * Ez a metodus vizsgalja meg, hogy az uj kaja koordinatai egybe esnek e a kigyo valamelyik
	 * testelemenek koordinataival. Ha egybe esnek false-ot, ha nem esnek egybe true-t terit vissza.
	 */
	public boolean megfelel(Point p){
		for (int i = 0; i <numberOfParts; i++){
			if ((arr[i].x == p.x) && (arr[i].y == p.y)){
				return false;
			}
		}
		return true;
	}
	
	/**
	 * A kigy mozgatasat megvalosito metodus, az aktualis irany szerint megfeleloen
	 * pozicionalja a fejet, majd a tobbi testresz sorba megkapja az elozo koordinatait.
	 * 
	 * Az if agon belul vizsgalja, hogy a kigyo epp utkozik e a fallal, vagy a sajat testevel.
	 */
	public boolean move() {
		
		if ( !intersectsBoundary() && !intersectsBody() ) {
			if ( direction == SnakeC.SNAKE_UP ) {
				top = top - SnakeC.SIZE;
			} else if ( direction == SnakeC.SNAKE_DOWN ) {
				top = top + SnakeC.SIZE;
			} else if ( direction == SnakeC.SNAKE_RIGHT ) {
				left = left + SnakeC.SIZE;
			} else if ( direction == SnakeC.SNAKE_LEFT ) {
				left = left - SnakeC.SIZE;
			}
			
			for (int i=numberOfParts-1; i>0; i--){
				int leftSnake = arr[i-1].x;
				int topSnake = arr[i-1].y;
				arr[i] = new Point( leftSnake, topSnake );
			}
			
			arr[0] = new Point(left, top);
		}
		else
		{
			return false;
		}
		return true;
	}
	/**
	 * Beallitja az aktualis iranyt.
	 * 
	 */
	public void setDirection( int dir ) {
		direction = dir;
	}
	
	/**
	 * Lekerdezi az aktualis iranyt.
	 */
	public int getDirection(){
		return direction;
	}
	
	/**
	 * Megvizsgalja, hogy a kigyo utkozott e neki a falnak. Ha a fal valamelyik reszen igen akkor, true-t
	 * kulonben false-ot terit vissza.
	 */
	public boolean intersectsBoundary() {	
		return  (arr[0].x < SnakeC.GAME_AREA.x || arr[0].y < SnakeC.GAME_AREA.y || 
				arr[0].x > SnakeC.GAME_AREA.width-15 || arr[0].y > SnakeC.GAME_AREA.height-15);
	}
	
	/**
	 * Mevizsgalja, hogy a kigyo utkozott e a sajat testevel. Ha igen akkor true-t, kulonben false-ot
	 * terit vissza.
	 */
	public boolean intersectsBody(){
		for (int i = 1; i<numberOfParts; i++){
			if ((arr[0].x == arr[i].x) && (arr[0].y == arr[i].y)){
				return true;
			}
		}
		return false;
	}
}
